package com.dragon.modules.yuegou.service.impl.member;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.yuegou.entity.member.PtTurntableEntity;
import com.dragon.modules.yuegou.entity.member.PtTurntableExtractPrizeEntity;
import com.dragon.modules.yuegou.entity.member.PtTurntablePageEntity;
import com.dragon.modules.yuegou.entity.member.PtTurntablePrizeEntity;
import com.dragon.modules.yuegou.entity.member.PtTurntablePrizeStoreEntity;
import com.dragon.modules.yuegou.entity.product.SkuEntity;
import com.dragon.modules.yuegou.entity.product.StockEntity;
import com.dragon.modules.yuegou.enums.code.MemberCode;
import com.dragon.modules.yuegou.enums.code.PointsCode;
import com.dragon.modules.yuegou.enums.member.PtTurntableCountWay;
import com.dragon.modules.yuegou.enums.member.PtTurntablePrizePrizeType;
import com.dragon.modules.yuegou.enums.order.OrderBuyerType;
import com.dragon.modules.yuegou.enums.order.OrderType;
import com.dragon.modules.yuegou.enums.points.DetailIncomeExpenses;
import com.dragon.modules.yuegou.enums.points.DetailSource;
import com.dragon.modules.yuegou.enums.points.DetailType;
import com.dragon.modules.yuegou.enums.product.StockChangeType;
import com.dragon.modules.yuegou.enums.system.ApplicationType;
import com.dragon.modules.yuegou.excel.member.PtTurntableExtractPrizeWorkbook;
import com.dragon.modules.yuegou.mapper.member.PtTurntableMapper;
import com.dragon.modules.yuegou.model.member.DistrictMember;
import com.dragon.modules.yuegou.model.member.PtTurntable;
import com.dragon.modules.yuegou.model.member.PtTurntableExtract;
import com.dragon.modules.yuegou.model.member.PtTurntableExtractPrize;
import com.dragon.modules.yuegou.model.member.PtTurntablePage;
import com.dragon.modules.yuegou.model.member.PtTurntablePrize;
import com.dragon.modules.yuegou.model.member.PtTurntablePrizeStore;
import com.dragon.modules.yuegou.model.member.PtTurntablePrizeXcx;
import com.dragon.modules.yuegou.model.member.PtTurntableXcx;
import com.dragon.modules.yuegou.model.order.Order;
import com.dragon.modules.yuegou.model.order.OrderItem;
import com.dragon.modules.yuegou.model.order.OrderPay;
import com.dragon.modules.yuegou.model.points.Detail;
import com.dragon.modules.yuegou.model.system.Application;
import com.dragon.modules.yuegou.model.system.Document;
import com.dragon.modules.yuegou.properties.PostersProperties;
import com.dragon.modules.yuegou.query.member.DistrictMemberQuery;
import com.dragon.modules.yuegou.query.member.PtTurntableExtractPrizeQuery;
import com.dragon.modules.yuegou.query.member.PtTurntablePageQuery;
import com.dragon.modules.yuegou.query.member.PtTurntablePrizeQuery;
import com.dragon.modules.yuegou.query.member.PtTurntablePrizeStoreQuery;
import com.dragon.modules.yuegou.query.member.PtTurntableQuery;
import com.dragon.modules.yuegou.query.product.StockQuery;
import com.dragon.modules.yuegou.service.member.DistrictMemberService;
import com.dragon.modules.yuegou.service.member.PtTurntableExtractPrizeService;
import com.dragon.modules.yuegou.service.member.PtTurntablePageService;
import com.dragon.modules.yuegou.service.member.PtTurntablePrizeService;
import com.dragon.modules.yuegou.service.member.PtTurntablePrizeStoreService;
import com.dragon.modules.yuegou.service.member.PtTurntableService;
import com.dragon.modules.yuegou.service.order.OrderService;
import com.dragon.modules.yuegou.service.points.DetailService;
import com.dragon.modules.yuegou.service.product.PostersService;
import com.dragon.modules.yuegou.service.product.SkuService;
import com.dragon.modules.yuegou.service.product.StockService;
import com.dragon.modules.yuegou.service.system.ApplicationService;
import com.dragon.modules.yuegou.service.system.DocumentService;
import com.dragon.modules.yuegou.utils.PageToResultUtils;
import com.dragon.modules.yuegou.utils.Random;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;

/**
 * 积分大转盘表 服务实现
 *
 * @author pbuilder generated
 * @version 2.0
 * @date 2021-12-16 19:20:45
 */
@Slf4j
@Service("memPtTurntableService")
public class PtTurntableServiceImpl
        extends ServiceImpl<PtTurntableMapper, PtTurntableEntity>
        implements PtTurntableService {

    protected static final String PT_TURNTABLE_CACHE_NAME = "ptTurntable";

    @Autowired
    private PtTurntablePageService ptTurntablePageService;

    @Autowired
    private PtTurntablePrizeService ptTurntablePrizeService;

    @Autowired
    private PtTurntableExtractPrizeService ptTurntableExtractPrizeService;

    @Autowired
    private PtTurntablePrizeStoreService ptTurntablePrizeStoreService;

    @Autowired
    private DistrictMemberService districtMemberService;

    @Autowired
    private DetailService detailService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private StockService stockService;

    private Cache ptTurntableCache;
    
	@Autowired
	private ApplicationService applicationService;
	
	@Autowired
	private PostersService postersService;
	
	@Autowired
	private PostersProperties postersProperties;

    @Autowired
    private DocumentService documentService;

    @Autowired
    public void setTurntableCacheManager(CacheManager cacheManager) {
        this.ptTurntableCache = cacheManager.getCache(PT_TURNTABLE_CACHE_NAME);
    }

    @Override
    public IPage<PtTurntable> search(PageRequest page, PtTurntableQuery query) {
        String title = query.getTitle();
        query.setTitle(null);
        query.title().like(title);
        QueryWrapper<PtTurntableEntity> wrapper = query.toQueryWrapper();
        wrapper.orderByDesc(PtTurntableEntity.COL_CREATED_TIME);
        IPage<PtTurntable> ptTurntableEntityIPage = this.page(PageToResultUtils.resultToPage(page), wrapper);
        if(CollectionUtils.isNotEmpty(ptTurntableEntityIPage.getRecords())){
            List<String> turntableIds = ptTurntableEntityIPage.getRecords().stream().map(PtTurntable::getId).distinct().collect(Collectors.toList());
            PtTurntablePageQuery ptTurntablePageQuery = new PtTurntablePageQuery();
            ptTurntablePageQuery.setTurntableIds(turntableIds);
            Map<String,List<PtTurntablePage>> ptTurntablePageMap = ptTurntablePageService.containsPage(ptTurntablePageQuery).stream().collect(Collectors.groupingBy(PtTurntablePage::getPointTurntableId));
            ptTurntableEntityIPage.getRecords().stream().forEach(data-> data.setPageList(ptTurntablePageMap.get(data.getId())));
        }
        return ptTurntableEntityIPage;
    }

    @Override
    @Transactional
    public void addPtTurntable(PtTurntable ptTurntable) {
        ptTurntable.setId(null);
        this.save(ptTurntable);
        savePtTurntable(ptTurntable.getPageList(), ptTurntable.getPrizeList(), ptTurntable.getId(), ptTurntable.getApplicationCode(), ptTurntable.getBusdId());
    }

    @Override
    @Transactional
    public void modifyPtTurntable(PtTurntable ptTurntable) {
        this.save(ptTurntable);
        editPtTurntable(ptTurntable.getPageList(), ptTurntable.getPrizeList(), ptTurntable.getId(), ptTurntable.getApplicationCode(), ptTurntable.getBusdId(),ptTurntable.getModifiedBy());
    }

    private void savePtTurntable(List<PtTurntablePage> pageList, List<PtTurntablePrize> prizeList, String turntableId, String applicationCode, String busdId) {
        this.saveTurntablePage(pageList,turntableId,applicationCode,busdId);

        if (CollectionUtils.isNotEmpty(prizeList)) {
            //验证奖品是否重复
            this.checkName(prizeList);
            //验证奖品数量是否足够
            this.checkStock(prizeList,"add");

            PtTurntablePrizeQuery query = new PtTurntablePrizeQuery();
            query.setPointTurntableId(turntableId);
            ptTurntablePrizeService.remove(query.toQueryWrapper());
            for (PtTurntablePrize prize : prizeList) {
                prize.setPointTurntableId(turntableId);
                ptTurntablePrizeService.save(prize);
                saveStore(prize, turntableId);
                //扣减实物奖品库存
                if (prize.getPrizeType() == PtTurntablePrizePrizeType.G1){
                    stockService.changeStock(prize.getGoodsId(),0-prize.getGoodsCount(), StockChangeType.TURNTABLE_PRIZE);
                }
            }
        }
    }

    private void editPtTurntable(List<PtTurntablePage> pageList, List<PtTurntablePrize> prizeList, String turntableId, String applicationCode, String busdId,String by) {
        this.saveTurntablePage(pageList,turntableId,applicationCode,busdId);
        if (CollectionUtils.isNotEmpty(prizeList)) {
            prizeList.stream().forEach(this::setPtTurntablePrize);
            //验证奖品是否重复
            this.checkName(prizeList);

            //验证奖品数量是否足够
            this.checkStock(prizeList,"edit");

            List<PtTurntablePrizeEntity> delPrizes  = this.delPrizes(turntableId,prizeList);

            if (CollectionUtils.isNotEmpty(delPrizes)){
                for (PtTurntablePrizeEntity prize : delPrizes) {
                    delPtTurntablePrize(prize,by);
                }

            }
            for (PtTurntablePrize prize : prizeList) {
                prize.setPointTurntableId(turntableId);
                this.changeStock(prize,turntableId);
            }
        }
    }

    private void setPtTurntablePrize(PtTurntablePrize ptTurntablePrize){
        if (ptTurntablePrize.getCurrentCount()==null){
            ptTurntablePrize.setCurrentCount(0);
        }
        PtTurntablePrizeEntity turntablePrize = ptTurntablePrizeService.getById(ptTurntablePrize.getId());
        if (turntablePrize!=null){
            setByPtTurntablePrizeEntity(ptTurntablePrize,turntablePrize);
        }else {
            ptTurntablePrize.setBeginChangeCount(0);
            if (ptTurntablePrize.getChangeCount()!=null){
                ptTurntablePrize.setGoodsCount(ptTurntablePrize.getChangeCount());
            }else {
                ptTurntablePrize.setChangeCount(ptTurntablePrize.getGoodsCount());
            }
            ptTurntablePrize.setEndChangeCount(ptTurntablePrize.getGoodsCount());
        }
        ptTurntablePrize.id(null);
    }

    private void setByPtTurntablePrizeEntity(PtTurntablePrize ptTurntablePrize,PtTurntablePrizeEntity turntablePrize){
        if (turntablePrize.getPrizeFlag() && ptTurntablePrize.getPrizeFlag()){
            hasPrizeFlag(ptTurntablePrize,turntablePrize);
        }else if (turntablePrize.getPrizeFlag() || ptTurntablePrize.getPrizeFlag()){
            //由不中奖商品改为中奖商品 或者不中奖改成中奖
            ptTurntablePrize.setBeginChangeCount(0);
            if (ptTurntablePrize.getChangeCount()!=null){
                ptTurntablePrize.setGoodsCount(ptTurntablePrize.getChangeCount());
            }else {
                ptTurntablePrize.setChangeCount(ptTurntablePrize.getGoodsCount());
            }
            ptTurntablePrize.setEndChangeCount(ptTurntablePrize.getChangeCount());
            if(ptTurntablePrize.getEndChangeCount() < 0){
                throw new DragonException(PointsCode.CANNOT_BE_LESS_THAN_ERROR);
            }
        }else {
            ptTurntablePrize.setBeginChangeCount(turntablePrize.getGoodsCount());
            if (ptTurntablePrize.getChangeCount()!=null){
                ptTurntablePrize.setGoodsCount(turntablePrize.getGoodsCount()+ptTurntablePrize.getChangeCount());
            }else {
                ptTurntablePrize.setChangeCount(ptTurntablePrize.getGoodsCount()-turntablePrize.getGoodsCount());
            }
            ptTurntablePrize.setEndChangeCount(ptTurntablePrize.getGoodsCount());
        }
    }

    private void hasPrizeFlag(PtTurntablePrize ptTurntablePrize,PtTurntablePrizeEntity turntablePrize){
        //都是中奖商品
        if (StringUtils.isNotEmpty(turntablePrize.getGoodsId())
                && StringUtils.isNotEmpty(ptTurntablePrize.getGoodsId())
                && turntablePrize.getGoodsId().equals(ptTurntablePrize.getGoodsId())){
            this.sameGoods(ptTurntablePrize,turntablePrize);
        }else if (StringUtils.isNotEmpty(turntablePrize.getGoodsId())
                && StringUtils.isNotEmpty(ptTurntablePrize.getGoodsId())){
            //不同商品
            ptTurntablePrize.setBeginChangeCount(0);
            if (ptTurntablePrize.getChangeCount()!=null){
                ptTurntablePrize.setGoodsCount(ptTurntablePrize.getChangeCount());
            }else {
                ptTurntablePrize.setChangeCount(ptTurntablePrize.getGoodsCount());
            }
            ptTurntablePrize.setEndChangeCount(ptTurntablePrize.getChangeCount());
            if(ptTurntablePrize.getEndChangeCount() < 0){
                throw new DragonException(PointsCode.CANNOT_BE_LESS_THAN_ERROR);
            }
        }else {
            if(ptTurntablePrize.getEndChangeCount() < 0){
                throw new DragonException(PointsCode.CANNOT_BE_LESS_THAN_ERROR);
            }
            if (ptTurntablePrize.getChangeCount()!=null){
                //相同商品
                ptTurntablePrize.setBeginChangeCount(turntablePrize.getGoodsCount());
                ptTurntablePrize.setGoodsCount(turntablePrize.getGoodsCount()+ptTurntablePrize.getChangeCount());
                ptTurntablePrize.setCurrentCount(ptTurntablePrize.getEndChangeCount());
            }else {
                //相同商品
                ptTurntablePrize.setBeginChangeCount(turntablePrize.getGoodsCount());
                ptTurntablePrize.setChangeCount(ptTurntablePrize.getGoodsCount()-turntablePrize.getGoodsCount());
                ptTurntablePrize.setEndChangeCount(turntablePrize.getGoodsCount()+ptTurntablePrize.getChangeCount());
            }

        }
    }

    private void sameGoods(PtTurntablePrize ptTurntablePrize,PtTurntablePrizeEntity turntablePrize){
        if (ptTurntablePrize.getChangeCount()!=null){
            //相同商品
            ptTurntablePrize.setBeginChangeCount(turntablePrize.getGoodsCount());
            ptTurntablePrize.setGoodsCount(turntablePrize.getGoodsCount()+ptTurntablePrize.getChangeCount());
            ptTurntablePrize.setCurrentCount(ptTurntablePrize.getEndChangeCount());
        }else {
            //相同商品
            ptTurntablePrize.setBeginChangeCount(turntablePrize.getGoodsCount());
            ptTurntablePrize.setChangeCount(ptTurntablePrize.getGoodsCount()-turntablePrize.getGoodsCount());
            ptTurntablePrize.setEndChangeCount(turntablePrize.getGoodsCount()+ptTurntablePrize.getChangeCount());
        }
        if(ptTurntablePrize.getEndChangeCount() < 0){
            throw new DragonException(PointsCode.CANNOT_BE_LESS_THAN_ERROR);
        }
    }
    private List<PtTurntablePrizeEntity> delPrizes(String turntableId,List<PtTurntablePrize> prizeList){
        List<PtTurntablePrizeEntity> delPrizes = new ArrayList<>();
        //计算奖品中奖
        PtTurntablePrizeQuery query = new PtTurntablePrizeQuery();
        query.setPointTurntableId(turntableId);
        query.setDel(false);
        List<PtTurntablePrizeEntity> prizes = ptTurntablePrizeService.list(query.toQueryWrapper());

        Map<String,PtTurntablePrize> prizeGoodsMap = prizeList.stream()
                .filter(ptTurntablePrize -> PtTurntablePrizePrizeType.G1.equals(ptTurntablePrize.getPrizeType()))
                .filter(ptTurntablePrize -> StringUtils.isNotEmpty(ptTurntablePrize.getGoodsId()))
                .collect(Collectors.toMap(PtTurntablePrize::getGoodsId, UnaryOperator.identity()));
        Map<String,PtTurntablePrize> prizeTitleMap = prizeList.stream()
                .filter(ptTurntablePrize -> PtTurntablePrizePrizeType.G2.equals(ptTurntablePrize.getPrizeType()))
                .filter(ptTurntablePrize -> StringUtils.isNotEmpty(ptTurntablePrize.getPrizeTitle()))
                .collect(Collectors.toMap(PtTurntablePrize::getPrizeTitle, UnaryOperator.identity()));
        for (PtTurntablePrizeEntity prize : prizes) {
            if (StringUtils.isNotEmpty(prize.getGoodsId())){
                PtTurntablePrize ptTurntablePrize = prizeGoodsMap.get(prize.getGoodsId());
                if (ptTurntablePrize ==null){
                    delPrizes.add(prize);
                }else {
                    ptTurntablePrize.setId(prize.getId());
                }
            }else if (StringUtils.isNotEmpty(prize.getPrizeTitle())){
                PtTurntablePrize ptTurntablePrize = prizeTitleMap.get(prize.getPrizeTitle());
                if (ptTurntablePrize ==null){
                    delPrizes.add(prize);
                }else {
                    ptTurntablePrize.setId(prize.getId());
                }
            }
        }
        return delPrizes;
    }

    private void delPtTurntablePrize(PtTurntablePrizeEntity prize,String by){
        if (PtTurntablePrizePrizeType.G1.equals(prize.getPrizeType())){
            PtTurntablePrizeStoreQuery storeQuery = new PtTurntablePrizeStoreQuery();
            storeQuery.prizeId().eq(prize.getId());
            storeQuery.goodsId().eq(prize.getGoodsId());
            List<PtTurntablePrizeStoreEntity> storeList = ptTurntablePrizeStoreService.list(storeQuery.toQueryWrapper());
            if (CollectionUtils.isNotEmpty(storeList)){
                PtTurntablePrizeStoreEntity store= storeList.get(0);
                stockService.changeStock(prize.getGoodsId(),store.getCurrentCount(), StockChangeType.TURNTABLE_PRIZE);

                store.setDel(true);
                ptTurntablePrizeStoreService.updateById(store);
            }
        }

        PtTurntablePrize updatePrize = new PtTurntablePrize();
        updatePrize.setId(prize.getId());
        updatePrize.setDel(true);
        updatePrize.setDelTime(LocalDateTime.now());
        updatePrize.setDelBy(by);
        ptTurntablePrizeService.updateById(updatePrize);
    }

    private void changeStock(PtTurntablePrize prize,String turntableId){
        if (StringUtils.isNotEmpty(prize.getId())){
            ptTurntablePrizeService.updateById(prize);
            modifyStore(prize, turntableId);
            if (PtTurntablePrizePrizeType.G1.equals(prize.getPrizeType())){
                stockService.changeStock(prize.getGoodsId(),0-prize.getChangeCount(), StockChangeType.TURNTABLE_PRIZE);
            }
        }else {
            ptTurntablePrizeService.save(prize);
            saveStore(prize, turntableId);
            if (PtTurntablePrizePrizeType.G1.equals(prize.getPrizeType())){
                stockService.changeStock(prize.getGoodsId(),0-prize.getGoodsCount(), StockChangeType.TURNTABLE_PRIZE);
            }
        }

    }


    private void saveTurntablePage(List<PtTurntablePage> pageList,String turntableId,String applicationCode, String busdId){
        PtTurntableQuery turntableQuery = new PtTurntableQuery();
        turntableQuery.setApplicationCode(applicationCode);
        turntableQuery.setDel(false);
        turntableQuery.setEnableStatus(true);
        List<String> turntableIds = new ArrayList<>();
        turntableIds.add(turntableId);
        turntableQuery.id().notIn(turntableIds);
        turntableQuery.setBusdId(busdId);
        List<PtTurntableEntity> ptTurntables = this.list(turntableQuery.toQueryWrapper());

        if (CollectionUtils.isNotEmpty(pageList)) {
            PtTurntablePageQuery query = new PtTurntablePageQuery();
            query.setPointTurntableId(turntableId);
            ptTurntablePageService.remove(query.toQueryWrapper());
            for (PtTurntablePage page : pageList) {
                page.setPointTurntableId(turntableId);
                //是否存在页面相同配置
                if (CollectionUtils.isNotEmpty(ptTurntables)) {
                    PtTurntablePageQuery containsPage = new PtTurntablePageQuery();
                    List<String> ids = ptTurntables.stream().map(PtTurntableEntity::getId).collect(Collectors.toList());
                    containsPage.pointTurntableId().in(ids);
                    List<PtTurntablePageEntity> turntablePages = ptTurntablePageService.list(containsPage.toQueryWrapper());
                    if (CollectionUtils.isNotEmpty(turntablePages)) {
                        List<String> turntablePageCodeList = turntablePages.stream().map(PtTurntablePageEntity::getPageCode).collect(Collectors.toList());
                        if (turntablePageCodeList.contains(page.getPageCode())) {
                            throw new DragonException(MemberCode.MEMBER_TURNTABLE_EXIST);
                        }
                    }
                }
                ptTurntablePageService.save(page);
            }
        }

    }

    private void checkTurntablePageCode(List<PtTurntablePageEntity> pageList,String turntableId,String applicationCode, String busdId){
        PtTurntableQuery turntableQuery = new PtTurntableQuery();
        turntableQuery.setApplicationCode(applicationCode);
        turntableQuery.setDel(false);
        turntableQuery.setEnableStatus(true);
        List<String> turntableIds = new ArrayList<>();
        turntableIds.add(turntableId);
        turntableQuery.id().notIn(turntableIds);
        turntableQuery.setBusdId(busdId);
        List<PtTurntableEntity> ptTurntables = this.list(turntableQuery.toQueryWrapper());

        if (CollectionUtils.isNotEmpty(pageList)) {
            for (PtTurntablePageEntity page : pageList) {
                page.setPointTurntableId(turntableId);
                //是否存在页面相同配置
                if (CollectionUtils.isNotEmpty(ptTurntables)) {
                    PtTurntablePageQuery containsPage = new PtTurntablePageQuery();
                    List<String> ids = ptTurntables.stream().map(PtTurntableEntity::getId).collect(Collectors.toList());
                    containsPage.pointTurntableId().in(ids);
                    List<PtTurntablePageEntity> turntablePages = ptTurntablePageService.list(containsPage.toQueryWrapper());
                    if (CollectionUtils.isNotEmpty(turntablePages)) {
                        List<String> turntablePageCodeList = turntablePages.stream().map(PtTurntablePageEntity::getPageCode).collect(Collectors.toList());
                        if (turntablePageCodeList.contains(page.getPageCode())) {
                            throw new DragonException(MemberCode.MEMBER_TURNTABLE_EXIST);
                        }
                    }
                }
            }
        }

    }

    private void checkName(List<PtTurntablePrize> prizeList){
        List<PtTurntablePrize> g1List = prizeList.stream().filter(s -> s.getPrizeType() == PtTurntablePrizePrizeType.G1).collect(Collectors.toList());
        long countG1 = g1List.stream().map(PtTurntablePrize::getGoodsId).distinct().count();
        if (countG1 < g1List.size()){
            throw new DragonException(PointsCode.G1_GOODS_REPEAT);
        }
        List<PtTurntablePrize> g2List = prizeList.stream().filter(s -> s.getPrizeType() == PtTurntablePrizePrizeType.G2).collect(Collectors.toList());
        long countG2 = g2List.stream().map(PtTurntablePrize::getPrizeTitle).distinct().count();
        if (countG2 < g2List.size()){
            throw new DragonException(PointsCode.G2_PRIZE_TITLE_REPEAT);
        }
    }

    private void checkStock(List<PtTurntablePrize> prizeList,String type){
        //验证奖品数量是否足够
        List<String> skuIdList = prizeList.stream()
                .filter(ptTurntablePrize -> PtTurntablePrizePrizeType.G1.equals(ptTurntablePrize.getPrizeType()))
                .map(PtTurntablePrize::getGoodsId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(skuIdList)){
            return;
        }

        StockQuery stockQuery = new StockQuery();
        stockQuery.skuId().in(skuIdList);
        List<StockEntity> stockList = stockService.list(stockQuery.toQueryWrapper());
        if (CollectionUtils.isEmpty(stockList)){
            throw new DragonException(PointsCode.ALL_GOODS_NOT_STOCK);
        }
        if (skuIdList.size() !=stockList.size()){
            throw new DragonException(PointsCode.EXIST_GOODS_NOT_STOCK);
        }

        Map<String,Integer> stockMap = stockList.stream().collect(Collectors.toMap(StockEntity::getSkuId,StockEntity::getStock));
        Map<String,List<PtTurntablePrize>> prizeMap = prizeList.stream()
                .filter(ptTurntablePrize -> PtTurntablePrizePrizeType.G1.equals(ptTurntablePrize.getPrizeType()))
                .collect(Collectors.groupingBy(PtTurntablePrize::getGoodsId));

        for (Map.Entry<String,List<PtTurntablePrize>> entry : prizeMap.entrySet()) {
            String skuId = entry.getKey();
            List<PtTurntablePrize> prizes = entry.getValue();

            Integer stock = stockMap.get(skuId);
            String goodsName = prizes.get(0).getGoodsName();
            Integer goodsCount = 0;
            if ("add".equals(type)){
                goodsCount = prizes.stream().mapToInt(PtTurntablePrize::getGoodsCount).sum();
            }else if ("edit".equals(type)){
                //编辑的时候变大才比较库存
                goodsCount = prizes.stream().mapToInt(PtTurntablePrize::getChangeCount).sum();
                log.debug(skuId +"商品变更数量={}，库存={}",goodsCount,stock);
            }
            if (stock ==null || goodsCount > stock){
                throw new DragonException(PointsCode.INSUFFICIENT_INVENTORY_TWO_ERROR.getCode(),
                        String.format(PointsCode.INSUFFICIENT_INVENTORY_TWO_ERROR.getMessage(),goodsName,stock));
            }
        }
    }

    public void modifyStore(PtTurntablePrize prize, String turntableId) {
        //编辑库存
        ptTurntablePrizeStoreService.modifyStore(turntableId,prize.getId(),prize.getChangeCount());
    }

    public void saveStore(PtTurntablePrize prize, String turntableId) {
        //保存库存
        PtTurntablePrizeStore store = new PtTurntablePrizeStore();
        store.setPointTurntableId(turntableId);
        store.setPrizeId(prize.getId());
        store.setGoodsId(prize.getGoodsId());
        store.setStoreCount(prize.getGoodsCount());
        store.setCurrentCount(prize.getGoodsCount());
        //是否是编辑
        PtTurntablePrizeStoreQuery query = new PtTurntablePrizeStoreQuery();
        query.setPrizeId(prize.getId());
        query.setDel(false);
        PtTurntablePrizeStoreEntity oldStore = ptTurntablePrizeStoreService.getOne(query.toQueryWrapper());
        if (oldStore != null) {
            store.setId(oldStore.getId());
            store.setCurrentCount(oldStore.getCurrentCount());
        }
        ptTurntablePrizeStoreService.save(store);
    }


    @Override
    public PtTurntable getPtTurntable(String id) {
        if (StringUtils.isEmpty(id)){
            return new PtTurntable();
        }
        PtTurntableEntity entity = this.getById(id);
        if (entity==null){
            return new PtTurntable();
        }
        PtTurntable ptTurntable = new PtTurntable(entity);
        PtTurntablePageQuery pageQuery = new PtTurntablePageQuery();
        pageQuery.setPointTurntableId(id);
        List<PtTurntablePageEntity> pageList = ptTurntablePageService.list(pageQuery.toQueryWrapper());
        ptTurntable.setPageList(pageList.stream().map(PtTurntablePage::new).collect(Collectors.toList()));
        //奖品
        PtTurntablePrizeQuery prizeQuery = new PtTurntablePrizeQuery();
        prizeQuery.setPointTurntableId(id);
        prizeQuery.setDel(false);
        QueryWrapper<PtTurntablePrizeEntity> wrapper = prizeQuery.toQueryWrapper();
        wrapper.orderByAsc(PtTurntablePrizeEntity.COL_GOODS_SORT);
        List<PtTurntablePrizeEntity> prizeList = ptTurntablePrizeService.list(wrapper);
        if (CollectionUtils.isNotEmpty(prizeList)) {
            ptTurntable.setPrizeList(prizeList.stream().map(PtTurntablePrize::new).collect(Collectors.toList()));
            ptTurntable.getPrizeList().stream().forEach(data ->{
                PtTurntablePrizeStoreQuery prizeStoreQuery = new PtTurntablePrizeStoreQuery();
                prizeStoreQuery.setPrizeId(data.getId());
                prizeStoreQuery.setDel(false);
                PtTurntablePrizeStoreEntity store = ptTurntablePrizeStoreService.getOne(prizeStoreQuery.toQueryWrapper());
                if(store != null) {
                    data.setCurrentCount(store.getCurrentCount());
                    data.setGainCount(data.getGoodsCount()-store.getCurrentCount());
                }
        	});
        }
        return ptTurntable;
    }

    @Override
    @Transactional
    public PtTurntableXcx getTurntableXcx(String busdId, String pageCode, ApplicationType applicationType, Boolean isXcx) {
        PtTurntablePageQuery ptTurntablePage = new PtTurntablePageQuery();
        ptTurntablePage.setPageCode(pageCode);
        List<PtTurntablePageEntity> list = ptTurntablePageService.list(ptTurntablePage.toQueryWrapper());
        if (CollectionUtils.isEmpty(list)) {
            throw new DragonException(Boolean.TRUE.equals(isXcx)? MemberCode.MEMBER_TURNTABLE_NOTFOUND : MemberCode.MEMBER_TURNTABLE_NOTFOUND1);
        }
        List<String> ids = list.stream().map(PtTurntablePageEntity::getPointTurntableId).collect(Collectors.toList());
        //查询积分大转盘
        LocalDateTime localDateTime = LocalDateTime.now();
        PtTurntableQuery query = new PtTurntableQuery();

        query.id().in(ids);
        query.setApplicationCode(applicationType.getCode().toString());
        query.setBusdId(busdId);
        query.setDel(false);
        query.setEnableStatus(true);

        //开始时间条件
        query.startTime().le(localDateTime);
        //结束时间条件
        query.endTime().ge(localDateTime);

        List<PtTurntableEntity> ptTurntables = this.list(query.toQueryWrapper());

        if (CollectionUtils.isEmpty(ptTurntables)) {
            throw new DragonException(Boolean.TRUE.equals(isXcx) ? MemberCode.MEMBER_TURNTABLE_NOTFOUND : MemberCode.MEMBER_TURNTABLE_NOTFOUND1);
        }

        PtTurntableXcx ptTurntableXcx = new PtTurntableXcx(ptTurntables.get(0));

        //奖品
        PtTurntablePrizeQuery prizeQuery = new PtTurntablePrizeQuery();
        prizeQuery.setPointTurntableId(ptTurntables.get(0).getId());
        prizeQuery.setDel(false);
        QueryWrapper<PtTurntablePrizeEntity> wrapper = prizeQuery.toQueryWrapper();
        wrapper.orderByAsc(PtTurntablePrizeEntity.COL_GOODS_SORT);
        List<PtTurntablePrizeEntity> prizeList = ptTurntablePrizeService.list(wrapper);

        if (CollectionUtils.isNotEmpty(prizeList)) {
            ptTurntableXcx.setPrizeList(prizeList.stream().map(PtTurntablePrize::new).collect(Collectors.toList()));
            ptTurntableXcx.getPrizeList().stream().forEach(data ->{
                PtTurntablePrizeStoreQuery prizeStoreQuery = new PtTurntablePrizeStoreQuery();
                prizeStoreQuery.setPrizeId(data.getId());
                prizeStoreQuery.setDel(false);
                PtTurntablePrizeStoreEntity store = ptTurntablePrizeStoreService.getOne(prizeStoreQuery.toQueryWrapper());
                if(store != null) {
                    data.setCurrentCount(store.getCurrentCount());
                    data.setGainCount(data.getGoodsCount()-store.getCurrentCount());
                }
            });

            Integer totalCount = ptTurntableXcx.getPrizeList().stream().mapToInt(PtTurntablePrize::getCurrentCount).sum();
            ptTurntableXcx.setTotalCount(totalCount);
        }


        PtTurntableExtract extract = new PtTurntableExtract();
        extract.setTurntableId(ptTurntables.get(0).getId());
        BigDecimal[] randomArg = prizeRate(extract, ptTurntables.get(0), prizeList);//获取中奖的奖品比率
        BigDecimal weightSum = BigDecimal.ZERO;
        for (BigDecimal weightValue : randomArg) {
            weightSum = weightSum.add(weightValue);

        }
        //总权重为0
        if (weightSum.compareTo(BigDecimal.ZERO) <= 0){
            ptTurntableXcx.setTotalCount(0);
        }
        return ptTurntableXcx;
    }

    @Override
    @Transactional
    public PtTurntablePrizeXcx extractPrize(PtTurntableExtract extract,Boolean isXcx) {
        //防止3秒内频繁点击
        String redisKey = extract.getMemberId() + "_" + extract.getTurntableId();
        Object exist = ptTurntableCache.get(redisKey);
        if (exist != null) {
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_EXTRACT_EXIST);
        }
        //获取大转盘

        PtTurntable ptTurntable = this.getPtTurntable(extract.getTurntableId());

        this.throwExcetion(extract,ptTurntable,isXcx);

        long maxExtractCount = checkStock(extract,ptTurntable);

        //校验积分
        DistrictMember districtMember = districtMemberService.createDistrictMember(extract.getMemberId(), extract.getBusdId());
        if (districtMember.getMemPoints() < ptTurntable.getConsumePoint()) {
            throw new DragonException(PointsCode.POINTS_INSUFFICIENT);
        }
        //获取奖品
        PtTurntablePrizeQuery prizeQuery = new PtTurntablePrizeQuery();
        prizeQuery.setPointTurntableId(extract.getTurntableId());
        QueryWrapper<PtTurntablePrizeEntity> wrapper = prizeQuery.toQueryWrapper();
        wrapper.orderByAsc(PtTurntablePrizeEntity.COL_GOODS_SORT);

        List<PtTurntablePrizeEntity> prizeList = ptTurntablePrizeService.list(wrapper);
        BigDecimal[] randomArg = prizeRate(extract, ptTurntable, prizeList);//获取中奖的奖品比率
        BigDecimal weightSum = BigDecimal.ZERO;
        for (BigDecimal weightValue : randomArg) {
            weightSum = weightSum.add(weightValue);

        }
        //总权重为0
        if (weightSum.compareTo(BigDecimal.ZERO) <= 0){
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_NO_PRIZE);
        }
        log.info("奖品权重数组:" + randomArg);

        PtTurntablePrizeEntity ptTurntablePrize = getPtTurntablePrize(randomArg, prizeList, 1);//获取奖品
        PtTurntablePrizeXcx ptTurntablePrizeXcx = new PtTurntablePrizeXcx(ptTurntablePrize);

        //设置中奖提示
        if (Boolean.TRUE.equals(ptTurntablePrize.getPrizeFlag())) {
            if (maxExtractCount > 0) {
                ptTurntablePrizeXcx.setTipsContent(ptTurntable.getPrizeRepeatContent());
            } else {
                ptTurntablePrizeXcx.setTipsContent(ptTurntable.getPrizeContent());
            }
            ptTurntablePrizeService.setPrizeFlag(extract.getMemberId());
        } else {
            ptTurntablePrizeXcx.setTipsContent(ptTurntable.getMissPrizeContent());
        }
        //保存redis key
        ptTurntableCache.put(redisKey, "exist");
        //积分扣减与增加
        DistrictMember updateDistrictMember = new DistrictMember();
        updateDistrictMember.setMemPoints(districtMember.getMemPoints() - ptTurntable.getConsumePoint());
        //扣除积分 + 是否中奖积分
        Order order = new Order();
        if (Boolean.TRUE.equals(ptTurntablePrize.getPrizeFlag())) {
            if (ptTurntablePrize.getPrizeType() != null && ptTurntablePrize.getPrizeType() == PtTurntablePrizePrizeType.G2 && ptTurntablePrize.getPointCount() != null) {
                //属于中奖中积分
                updateDistrictMember.setMemPoints(updateDistrictMember.getMemPoints() + ptTurntablePrize.getPointCount().intValue());
            } else if (ptTurntablePrize.getPrizeType() != null &&ptTurntablePrize.getPrizeType() == PtTurntablePrizePrizeType.G1 && ptTurntablePrize.getGoodsId() != null) {
                order = this.placeOrder(extract,ptTurntablePrize);
            }
        }
        updateDistrictMember.setVersion(districtMember.getVersion() + 1);
        this.savePointDetail(updateDistrictMember,districtMember,extract,ptTurntable,ptTurntablePrize);

        //保存记录
        PtTurntableExtractPrize ptTurntableExtractPrize = this.setPtTurntableExtractPrize(extract,ptTurntable,ptTurntablePrize,order.getId());
        ptTurntableExtractPrizeService.save(ptTurntableExtractPrize);
        return ptTurntablePrizeXcx;
    }

    private void throwExcetion(PtTurntableExtract extract,PtTurntable ptTurntable,Boolean isXcx){
        LocalDateTime localDateTime = LocalDateTime.now();
        if (ptTurntable == null) {
            throw new DragonException(Boolean.TRUE.equals(isXcx) ? MemberCode.MEMBER_TURNTABLE_NOTFOUND : MemberCode.MEMBER_TURNTABLE_NOTFOUND1);
        }
        if (ptTurntable.getStartTime().isAfter(localDateTime)) {
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_NOT_START);
        }
        if (ptTurntable.getEndTime().isBefore(localDateTime)) {
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_END);
        }
        if (!extract.getApplicationType().getCode().toString().equals(ptTurntable.getApplicationCode())) {
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_APP_NOTFOUND);
        }
    }

    private long checkStock(PtTurntableExtract extract,PtTurntable ptTurntable){
        LocalDateTime localDateTime = LocalDateTime.now();
        //抽奖最大次数。 每人每天抽奖最大次数
        PtTurntableExtractPrizeQuery extractPrizeQuery = new PtTurntableExtractPrizeQuery();
        extractPrizeQuery.setTurntableId(extract.getTurntableId());
        List<PtTurntableExtractPrizeEntity> extractPrizes = ptTurntableExtractPrizeService.list(extractPrizeQuery.toQueryWrapper());
        long maxCount = extractPrizes.stream().filter(ptTurntableExtractPrize -> ptTurntableExtractPrize.getMemberId().equals(extract.getMemberId())).count();
        if (maxCount >= ptTurntable.getMaxCount()) {
            log.error("会员抽奖次数已经达到最大次数.maxCountLog:{},maxCount:{}", maxCount, ptTurntable.getMaxCount());
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_MAX_PRIZE);
        }
        long maxExtractCount = extractPrizes.stream()
                .filter(ptTurntableExtractPrize ->
                        (ptTurntableExtractPrize.getCreatedTime().isBefore(localDateTime.withHour(23).withMinute(59).withSecond(59)) &&
                                ptTurntableExtractPrize.getCreatedTime().isAfter(localDateTime.withHour(0).withMinute(0).withSecond(0)) &&
                                ptTurntableExtractPrize.getMemberId().equals(extract.getMemberId()))).count();
        if (maxExtractCount >= ptTurntable.getMaxExtractCount()) {
            log.error("会员今日抽奖次数已经达到最大次数.memberId:{},maxCountLog:{},maxCount:{}", extract.getMemberId(), maxExtractCount, ptTurntable.getMaxExtractCount());
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_TOYDAY_MAX_EXTRACT_PRIZE);
        }
        return maxExtractCount;
    }

    private Order placeOrder(PtTurntableExtract extract,PtTurntablePrizeEntity ptTurntablePrize){
        //中实物奖品
        Order order = new Order();
        order.setType(OrderType.LOTTERY);
        order.setBusdId(extract.getBusdId());
        order.setBuyerId(extract.getMemberId());
        order.setBuyerType(OrderBuyerType.MEMBER);
        //设置商品
        List<OrderItem> orderItemList = new ArrayList<>();
        OrderItem orderItem = new OrderItem();
        orderItem.setNum(1);
        orderItem.setSkuId(ptTurntablePrize.getGoodsId());
        orderItem.setSkuTitle(ptTurntablePrize.getPrizeTitle());
        orderItem.setSkuMainImages(ptTurntablePrize.getGoodsImg());
        orderItemList.add(orderItem);
        order.setOrderItemList(orderItemList);
        SkuEntity sku = skuService.getById(ptTurntablePrize.getGoodsId());
        if (Objects.isNull(sku)) {
            throw new DragonException(MemberCode.MEMBER_TURNTABLE_SKU_NOTFOUND);
        }
        order.setCouponAmount(sku.getDiscountPrice());// 优惠金额
        order = orderService.placeOrder(order,true);

        //0元支付
        OrderPay payinfo = new OrderPay();
        payinfo.setOrderNo(order.getId());
        payinfo.setPayCash(order.getPayableAmount());
        payinfo.setPayTime(LocalDateTime.now());
        orderService.payZeroOrder(payinfo);
        return order;
    }

    private void savePointDetail(DistrictMember updateDistrictMember,DistrictMember districtMember,PtTurntableExtract extract,
                                 PtTurntable ptTurntable,PtTurntablePrizeEntity ptTurntablePrize){
        DistrictMemberQuery member = new DistrictMemberQuery();
        member.setId(districtMember.getId());
        member.setVersion(districtMember.getVersion());
        Boolean modify = districtMemberService.update(updateDistrictMember, member.toQueryWrapper());
        if (Boolean.TRUE.equals(modify)) {
            // 插入扣减积分明细
            Detail detail = new Detail();
            detail.busdId(extract.getBusdId());
            detail.setMemberId(extract.getMemberId());
            detail.setType(DetailType.EXTRACT);
            detail.setSource(DetailSource.EXTRACT);
            detail.setIncomeExpenses(DetailIncomeExpenses.EXPENSES);
            detail.setPoints(ptTurntable.getConsumePoint());
            detail.setDel(false);
            detailService.save(detail);
            // 插入添加积分明细
            if (Boolean.TRUE.equals(ptTurntablePrize.getPrizeFlag()) && ptTurntablePrize.getPointCount() != null) {
                Detail prizeDetail = new Detail();
                prizeDetail.busdId(extract.getBusdId());
                prizeDetail.setMemberId(extract.getMemberId());
                prizeDetail.setType(DetailType.PRIZE);
                prizeDetail.setSource(DetailSource.EXTRACT);
                prizeDetail.setIncomeExpenses(DetailIncomeExpenses.INCOME);
                prizeDetail.setPoints(ptTurntablePrize.getPointCount().intValue());
                prizeDetail.setDel(false);
                detailService.save(prizeDetail);
            }
        }
    }

    private PtTurntableExtractPrize setPtTurntableExtractPrize(PtTurntableExtract extract,PtTurntable ptTurntable,PtTurntablePrizeEntity ptTurntablePrize,String orderNo){
        PtTurntableExtractPrize ptTurntableExtractPrize = new PtTurntableExtractPrize();
        ptTurntableExtractPrize.setTurntableId(extract.getTurntableId());
        ptTurntableExtractPrize.setBusdId(extract.getBusdId());
        ptTurntableExtractPrize.setConsumePoint(ptTurntable.getConsumePoint());
        ptTurntableExtractPrize.setPageCode(extract.getPageCode());
        ptTurntableExtractPrize.setPrizeId(ptTurntablePrize.getId());
        ptTurntableExtractPrize.setMemberId(extract.getMemberId());
        ptTurntableExtractPrize.setMemberName(extract.getMemberName());
        ptTurntableExtractPrize.setGainPrize(Boolean.TRUE.equals(ptTurntablePrize.getPrizeFlag()));
        if (null != ptTurntablePrize.getPrizeType() && ptTurntablePrize.getPrizeType() == PtTurntablePrizePrizeType.G1 && StringUtils.isNotEmpty(orderNo)){
            ptTurntableExtractPrize.setGoodsId(ptTurntablePrize.getGoodsId());
        }
        ptTurntableExtractPrize.setGoodsName(ptTurntablePrize.getPrizeTitle());
        ptTurntableExtractPrize.setOrderId(orderNo);
        ptTurntableExtractPrize.setCreatedBy(extract.getMemberId());
        ptTurntableExtractPrize.setCreatedTime(LocalDateTime.now());
        ptTurntableExtractPrize.setReceiveStatus(false);
        return ptTurntableExtractPrize;
    }

    public BigDecimal[] prizeRate(PtTurntableExtract extract, PtTurntableEntity ptTurntable, List<PtTurntablePrizeEntity> prizeList) {
        //获取奖品库存
        PtTurntablePrizeStoreQuery prizeStoreQuery = new PtTurntablePrizeStoreQuery();
        prizeStoreQuery.setPointTurntableId(extract.getTurntableId());
        prizeStoreQuery.setDel(false);
        List<PtTurntablePrizeStoreEntity> storeList = ptTurntablePrizeStoreService.list(prizeStoreQuery.toQueryWrapper());
        Map<String, Integer> storeMap = storeList.stream().collect(Collectors.toMap(PtTurntablePrizeStoreEntity::getPrizeId, PtTurntablePrizeStoreEntity::getCurrentCount));
        //中奖概率
        BigDecimal gainProbability = ptTurntable.getGainProbability();

        Integer gainSumConfig = this.gainSumConfig(ptTurntable,prizeList,storeMap);
        //不中奖概率
        BigDecimal missProbability = ptTurntable.getMissProbability();

        Integer missSumConfig = this.missSumConfig(ptTurntable,prizeList,storeMap);

        //封装权重奖品数组
        BigDecimal[] randomArg = new BigDecimal[prizeList.size()];
        for (int i = 0; i < prizeList.size(); i++) {
            PtTurntablePrizeEntity ptTurntablePrize = prizeList.get(i);
            randomArg[i] = this.weight(ptTurntablePrize,ptTurntable,storeMap,gainProbability,gainSumConfig,missProbability,missSumConfig);
        }
        return randomArg;
    }

    private Integer gainSumConfig(PtTurntableEntity ptTurntable,List<PtTurntablePrizeEntity> prizeList,Map<String, Integer> storeMap){
        Integer gainSumConfig = 0;
        List<PtTurntablePrizeEntity> gainList = prizeList.stream().filter(ptTurntablePrize -> Boolean.TRUE.equals(ptTurntablePrize.getPrizeFlag())).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(gainList)) {
            for (PtTurntablePrizeEntity data : gainList) {
                if (PtTurntableCountWay.SURPLUS.equals(ptTurntable.getCountWay())) {
                    if(storeMap.get(data.getId()) != null){
                        gainSumConfig += storeMap.get(data.getId());
                    }
                } else {
                    gainSumConfig += data.getGoodsCount();
                }
            }
        }
        return gainSumConfig;
    }

    private Integer missSumConfig(PtTurntableEntity ptTurntable,List<PtTurntablePrizeEntity> prizeList,Map<String, Integer> storeMap){
        Integer missSumConfig = 0;
        List<PtTurntablePrizeEntity> missList = prizeList.stream().filter(ptTurntablePrize -> !ptTurntablePrize.getPrizeFlag()).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(missList)) {
            for (PtTurntablePrizeEntity data : missList) {
                if (PtTurntableCountWay.SURPLUS.equals(ptTurntable.getCountWay())) {
                    if(storeMap.get(data.getId()) != null){
                        missSumConfig += storeMap.get(data.getId());
                    }
                } else {
                    missSumConfig += data.getGoodsCount();
                }
            }
        }
        return missSumConfig;
    }

    private BigDecimal weight(PtTurntablePrizeEntity ptTurntablePrize,PtTurntableEntity ptTurntable,Map<String, Integer> storeMap,
                              BigDecimal gainProbability,Integer gainSumConfig,BigDecimal missProbability,Integer missSumConfig){
        BigDecimal weight = BigDecimal.ZERO;
        Integer goodsProbability = 0;
        if(PtTurntableCountWay.SURPLUS.equals(ptTurntable.getCountWay())) {
            if(storeMap.get(ptTurntablePrize.getId())!= null) {
                goodsProbability = storeMap.get(ptTurntablePrize.getId());
            }
        }else {
            goodsProbability = ptTurntablePrize.getGoodsCount();

        }
        if (Boolean.TRUE.equals(ptTurntablePrize.getPrizeFlag())) {
            if (gainSumConfig != 0)
                weight = new BigDecimal(goodsProbability).divide(new BigDecimal(gainSumConfig), 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(gainProbability);
        } else {
            if (missSumConfig != 0)
                weight = new BigDecimal(goodsProbability).divide(new BigDecimal(missSumConfig), 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(missProbability);
        }

        //如果不是商品无限大
        if (!storeMap.containsKey(ptTurntablePrize.getId()) || storeMap.get(ptTurntablePrize.getId()) == 0) {
            weight = BigDecimal.ZERO;
        }
        return weight;
    }

    private PtTurntablePrizeEntity getPtTurntablePrize(BigDecimal[] randomArg, List<PtTurntablePrizeEntity> prizeList, int count) {
        //调用抽奖的随机数
        Random.WeightRandom random = new Random.WeightRandom();
        int index = random.getWeightRandom(randomArg);//下标为获取的奖品
        PtTurntablePrizeEntity prize = prizeList.get(index);
        //是否够资格领取
        boolean receive = true;
        PtTurntablePrizeEntity ptTurntablePrize = prizeList.get(index);
        //库存
        PtTurntablePrizeStoreQuery prizeStoreQuery = new PtTurntablePrizeStoreQuery();
        prizeStoreQuery.setPrizeId(ptTurntablePrize.getId());
        prizeStoreQuery.setDel(false);
        PtTurntablePrizeStoreEntity store = ptTurntablePrizeStoreService.getOne(prizeStoreQuery.toQueryWrapper());
        if (store == null || store.getCurrentCount() == 0) {
            receive = false;
        }
        //会员领取情况
        if (receive) {
            Integer currentCount = store.getCurrentCount();
            currentCount--;
            store.setCurrentCount(currentCount);
            ptTurntablePrizeStoreService.updateById(store);
            return prize;
        } else {
            count++;
            if (count > 99) {
                //防止递归太多
                throw new DragonException(MemberCode.MEMBER_TURNTABLE_NO_PRIZE);
            }
            return getPtTurntablePrize(randomArg, prizeList, count);
        }
    }

	@Override
	public String generateCode(String turntableId, String busdId) {
		PtTurntableEntity ptTurntable = getById(turntableId);
		if (ptTurntable==null ){
			throw new DragonException(MemberCode.MEMBER_TURNTABLE_NOTFOUND);
		}
		// 查询application信息
        PtTurntablePageQuery ptTurntablePage = new PtTurntablePageQuery();
        ptTurntablePage.setPointTurntableId(turntableId);
        List<PtTurntablePageEntity> list = ptTurntablePageService.list(ptTurntablePage.toQueryWrapper());
		Application application = applicationService.getOriginalId(busdId);
		String path = String.format(postersProperties.getTurntableurl(), busdId,CollectionUtils.isEmpty(list)?"":list.get(0).getPageCode());
		return postersService.getMiniCode(path, application.getAppid(), application.getAppsecret());
	}

    @Override
    public IPage<PtTurntableExtractPrize> getExtractPrize(PageRequest pageInfo,PtTurntableExtractPrizeQuery query) {
        //获取参加大转盘的会员
        return ptTurntableExtractPrizeService.searchList(PageToResultUtils.resultToPage(pageInfo),query);
    }

    @Override
    public Document exportExtractPrize(PtTurntableExtractPrizeQuery query) {
        List<PtTurntableExtractPrize> prizeList = ptTurntableExtractPrizeService.searchList(query);

        PtTurntableExtractPrizeWorkbook ptTurntableExtractPrizeWorkbook = new PtTurntableExtractPrizeWorkbook();
        List<PtTurntableExtractPrizeWorkbook.PtTurntableExtractPrizeRow> prizeRows = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(prizeList)) {
            for (PtTurntableExtractPrize prize : prizeList) {
                PtTurntableExtractPrizeWorkbook.PtTurntableExtractPrizeRow row = new PtTurntableExtractPrizeWorkbook.PtTurntableExtractPrizeRow();
                row.setMemberMobile(prize.getMemberMobile());
                row.setGoodsName(prize.getGoodsName());
                if (Boolean.FALSE.equals(prize.getGainPrize())){
                    row.setReceiveStatus("/");
                    row.setGainPrize("未中奖");
                }else{
                    row.setReceiveStatus(Boolean.TRUE.equals(prize.getReceiveStatus())?"已核销":"未核销");
                    row.setGainPrize("已中奖");
                }
                row.setOrderId(prize.getId());
                row.setMerchant(StringUtils.isEmpty(prize.getMerchantName())?"/":prize.getMerchantName());
                prizeRows.add(row);
            }
        }
        ptTurntableExtractPrizeWorkbook.setPtTurntableExtractPrize(prizeRows);
        return documentService.generateExcel("大转盘抽奖记录表.xlsx", ptTurntableExtractPrizeWorkbook);
    }

    @Override
    public void modifyStatus(PtTurntable ptTurntable) {
        if (Boolean.TRUE.equals(ptTurntable.getEnableStatus())){
            PtTurntableEntity turntable = this.getById(ptTurntable.getId());
            //检测活动位置是否重复

            PtTurntablePageQuery pageQuery = new PtTurntablePageQuery();
            pageQuery.setPointTurntableId(ptTurntable.getId());
            List<PtTurntablePageEntity>  pageList = ptTurntablePageService.list(pageQuery.toQueryWrapper());
            this.checkTurntablePageCode(pageList,ptTurntable.getId(),turntable.getApplicationCode(),turntable.getBusdId());
        }
        this.baseMapper.updateById(ptTurntable);
    }

}